import { onMounted } from 'vue'
import { onPullDownRefresh } from '@dcloudio/uni-app'

/**
 * 分页组件基础配置属性
 */
export interface PageProps<T = any> {
    // 是否在创建页面时即调用数据列表接口，默认为true
    createdIsNeed?: boolean
    // 是否需要分页，默认为true
    isPage?: boolean
    // 查询条件表单对象，类型为any
    params?: any
    // 数据列表数组
    data?: T[]
    // 分页属性对象
    pagination?: Pagination
    // 数据列表，loading状态标志，默认为false
    dataListLoading?: boolean
    // 数据列表多选项数组
    dataListSelections?: any[]
    // 数据列表查询接口api方法，接收任意数量参数，返回Promise
    fetchData?: (...arg: any) => Promise<any>
    // loading标志，默认为false
    loading?: boolean
    // 多选结果数组
    selectObjs?: any[]
    // 排序字段数组
    descs?: string[]
    // 排序方式数组
    ascs?: string[]
    // props属性对象，类型为any
    props?: any
    // 下拉刷新标志，默认为false
    pullRefreshState?: boolean
    // 重载之前调用的方法
    beforeLoadingFn?: () => void
}

/**
 * 分页属性配置接口
 */
export interface Pagination {
    // 当前页码，默认为1
    current?: number
    // 每页显示条数，默认为10
    size?: number
    // 总条数，默认为0
    total?: number
}

export const defaultOptions: PageProps = {
    // 列表数据是否正在加载中，默认为false
    dataListLoading: false,
    // 是否需要自动请求创建接口来获取数据，默认为true
    createdIsNeed: true,
    // 是否展示分页组件，默认为true
    isPage: true,
    // 查询表单对象，用于提交条件查询时的参数传递，默认为空对象
    params: {},
    // 展示的数据数组，默认为空数组
    data: [],
    // 分页组件属性配置，如当前页码、每页展示数据条数等，默认值为 {current:1, size:10,total:0}
    pagination: {
        current: 1,
        size: 10,
        total: 0
    } as Pagination,
    // 当前选中的数据项，默认为空数组
    dataListSelections: [],
    // 是否正在从服务器加载数据，默认为false
    loading: false,
    // 数据项的选择数据，默认为空数组
    selectObjs: [],
    // 排序时使用的字段名数组，如 ['id','name']，默认为空数组
    descs: [],
    // 排序方向数组，如 ['asc', 'desc']，默认为空数组
    ascs: [],
    // props属性配置对象，用于自定义数据属性，默认值为 {item:'records',totalCount:'total'}
    props: {
        item: 'records',
        totalCount: 'total'
    },
    // 下拉刷新标志，默认为false
    pullRefreshState: false
}

/**
 * 合并默认属性配置和自定义属性配置
 * @param options 默认属性配置对象
 * @param props 自定义属性配置对象
 * @returns 合并后的属性配置对象
 */
export const mergeDefaultOptions = (options: any, props: any): PageProps => {
    for (const key in options) {
        if (!Object.getOwnPropertyDescriptor(props, key)) {
            props[key] = options[key]
        }
    }
    return props
}

/**
 * 分页组件基础配置属性
 * @param options
 */
export function usePage(options?: PageProps) {
    // 覆盖默认值
    const state = mergeDefaultOptions(defaultOptions, options)

    /**
     * 发起分页查询，并设置数据和分页信息
     */
    const query = async () => {
        // 判断是否存在state.fetchData属性
        if (state.fetchData) {
            try {
                // 开始加载数据，设置state.loading为true
                state.loading = true

                const current = state.pagination?.current

                // 调用state.pageList方法发起分页查询
                const res = await state.fetchData({
                    ...state.params,
                    current: current,
                    size: state.pagination?.size,
                    descs: state.descs?.join(','),
                    ascs: state.ascs?.join(',')
                })

                // 设置展示的数据数组
                state.data = state.data?.concat(
                    state.isPage ? res.data[state.props.item] : res.data
                )
                // 设置分页信息中的总数据条数
                state.pagination!.total = state.isPage ? res.data[state.props.totalCount] : 0

                // 当前页大于等于总页数时，将当前页码设置为总页数
                if (Number(current) >= res.data.pages) {
                    state.pagination!.current = res.data.pages
                }
            } catch (err: any) {
                // 捕获异常并显示错误提示
                uni.$u.toast(err.msg || err.data.msg)
            } finally {
                // 结束加载数据，设置state.loading为false
                state.loading = false
                if (state.pullRefreshState) {
                    state.pullRefreshState = false
                    uni.stopPullDownRefresh()
                }
            }
        }
    }

    onMounted(() => {
        if (state.createdIsNeed) {
            query()
        }
    })

    // 下拉刷新
    onPullDownRefresh(() => {
        console.log('onPullDownRefresh')
        state.pullRefreshState = true
        getDataList(true)
    })

    /**
     * 分页大小改变事件处理函数
     * @param val 新的分页大小
     */
    const sizeChangeHandle = (val: number) => {
        // 修改state.pagination中的size属性
        state.pagination!.size = val
        // 再次发起查询操作
        query()
    }

    /**
     * 当前页码改变事件处理函数
     * @param val 新的页码
     */
    const currentChangeHandle = (val: number) => {
        // 修改state.pagination中的current属性
        state.pagination!.current = val
        // 再次发起查询操作
        query()
    }

    /**
     * 获取数据列表，并可选择是否刷新当前页码
     * 刷新后不跳转第一页，则入参 getDataList(false)
     * @param refresh 是否刷新当前页码
     */
    const getDataList = (refresh?: any) => {
        // 如果需要刷新，则将state.pagination.current重置为1
        if (refresh !== false) {
            state.pagination!.current = 1
            state.data = []
        }
        // 再次发起查询操作
        query()
    }

    return {
        getDataList,
        sizeChangeHandle,
        currentChangeHandle
    }
}
